package org.dandsoft.blackbox.laboratory.tools.view;

import org.dandsoft.blackbox.laboratory.tools.JCRMonitorStorage;
import org.dandsoft.blackbox.snn.Time;
import org.dandsoft.blackbox.snn.ObjectId;
import org.dandsoft.blackbox.snn.Signal;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.Arrays;
import java.io.DataInputStream;

/**
 * Created by IntelliJ IDEA.
 * User: dvilyuzhanin
 * Date: 29.03.2009 21:14:10
 */
public class EnviromentStateView extends JPanel {
    private float zoom = 1;
    private float zoomStep = 2;
    private JCRMonitorStorage storage;
    private Canvas canvas;
    private Dimension canvasSize = new Dimension(640, 480);
    private JScrollPane scrollPane;

    public EnviromentStateView() {
        super.setLayout(new BorderLayout());
        canvas = new Canvas();
        canvas.setSize(canvasSize);
        scrollPane = new JScrollPane(canvas,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        add(scrollPane, BorderLayout.CENTER);
    }

    public void updateImage() {
        canvas.prepairImage();
        this.repaint();
    }

    class Canvas extends JPanel {
        int[][] data;

        public void resize() {
            canvasSize = new Dimension(Math.round(data[0].length * zoom), Math.round(data.length * zoom));
            this.setSize(canvasSize);
            this.setPreferredSize(canvasSize);
            this.setMaximumSize(canvasSize);

        }

        @Override
        protected void paintComponent(Graphics g) {
            if (data != null) {
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, (int) canvasSize.getWidth(), (int) canvasSize.getHeight());
                Rectangle viewRect = scrollPane.getViewport().getViewRect();
                int startId = 0;
                int finishId = data[0].length;
                int startTime = 0;
                int finishTime = data.length;

                if (canvasSize.getWidth() > viewRect.getWidth()) {
                    startId = (int) Math.round(viewRect.getX() / zoom);
                    finishId = startId + (int) Math.round(viewRect.getWidth() / zoom);
                }

                if (canvasSize.getHeight() > viewRect.getHeight()) {
                    startTime = (int) Math.round(viewRect.getY() / zoom);
                    finishTime = startTime + 1 + (int) Math.round(viewRect.getHeight() / zoom);
                    if (startTime > 0) {
                        startTime--;
                    }
                }
                for (int time = startTime; time < finishTime && time < data.length; time++) {
                    for (int id = startId; id < finishId && id < data[time].length; id++) {
                        if (data[time][id] != -1) {
                            g.setColor(ValueColorSpec.getColor(data[time][id]));
                        } else {
                            g.setColor(Color.WHITE);
                        }
                        g.fillRect(Math.round(id * zoom), Math.round(time * zoom), Math.round(zoom), Math.round(zoom));
                    }
                }
            }
           
        }


        public void prepairImage() {
            int height = (int) storage.getTimesCount();
            int width = storage.getMaxObjectId();
            canvasSize = new Dimension(width, height);

            data = new int[height][width];
            for (int i = 0; i < data.length; i++) {
                for (int j = 0; j < data[i].length; j++) {
                    data[i][j] = -1;
                }
            }
            for (int time = 0; time < height; time++) {
                Map<ObjectId, Signal> signals = storage.getEnviroment(new Time(time));
                if (signals != null) {
                    for (Map.Entry<ObjectId, Signal> entry : signals.entrySet()) {
                        float value = entry.getValue().getValue().getValue();
                        int index = (int) (Math.floor(value * ValueColorSpec.SCALE_SIZE)) - 1;
                        try {
                            data[time][entry.getKey().getValue() - 1] = index;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

    }

    public void zoomDown() {
        zoom += zoomStep;
        canvas.resize();
        repaint();

    }

    public void zoomUp() {
        zoom -= zoomStep;
        if (zoom < 1) {
            zoom = 1;
        }
        canvas.resize();
        repaint();
    }

    @Override
    public void repaint() {
        if (scrollPane != null) {
            scrollPane.revalidate();
        }
        super.repaint();
    }

    public void setNormalZoom() {
        zoom = 1;
    }

    public float getZoom() {
        return zoom;
    }

    public void setZoom(float zoom) {
        this.zoom = zoom;
    }

    public float getZoomStep() {
        return zoomStep;
    }

    public void setZoomStep(float zoomStep) {
        this.zoomStep = zoomStep;
    }

    public JCRMonitorStorage getStorage() {
        return storage;
    }

    public void setStorage(JCRMonitorStorage storage) {
        this.storage = storage;
    }
}
